<!DOCTYPE html>
<html lang="zh-CN">
<head>
  <meta charset="UTF-8">
  <meta name="viewport" content="width=device-width, initial-scale=1.0">
  <title>02key原理和作用</title>
  <script src="../js/vue.js"></script>
</head>
<body>
  <div id="app">
    <h1>{{title}}</h1>
    <h3>1遍历数组</h3>
    <!-- 
      key有什么作用？
        1 key是虚拟dom对象的标识，当数据发生改变时，Vue会根据新数据生成新的虚拟dom
        2 将新的虚拟dom和旧的虚拟dom进行对比
      
      对比规则？
        1 在新的虚拟dom中发现了和旧的虚拟dom相同的key值
          对比新旧虚拟dom内容，一样则直接复用
          内容有变化则生成新的真实dom替换页面中旧的真实dom
        2 在新的虚拟dom中未找到和旧的虚拟dom相同的key值
          根据新的虚拟dom直接创建新的真实dom然后渲染到页面中
      
      index作为key存在的问题？
        1 如果数据进行了逆序添加/删除等破坏顺序的操作，会产生不必要的真实dom更新，有时候不影响页面显示但影响性能
        2 如果结构中含有输入类的dom，还可能产生错误的dom更新，影响页面显示

      实际开发中key值如何选择？
        1 最好使用每条数据唯一的标识，例如id，手机号，身份证，学号等等
        2 如果不存在破坏顺序的操作，用index作未key值是可以的，但不严谨
     -->
    <ul>
      <li v-for="(p, index) in persons" :key="index">{{p.name}}-{{p.age}} <input type="text"> </li>
    </ul>
    <br>
    <ul>
      <li v-for="p of persons" :key="p.id">{{p.name}}-{{p.age}} <input type="text"> </li>
    </ul>
    <button @click="handlePush">push</button>
    <button @click="handleShift">shift</button>
  </div>
  <script>
    new Vue({
      el: '#app',
      data() {
        return {
          title: 'key原理和作用',
          persons: [
            {
              id: '001',
              name: 'zhangsan',
              age: 18
            },
            {
              id: '002',
              name: 'lisi',
              age: 18
            },
            {
              id: '003',
              name: 'wangwu',
              age: 18
            }
          ]
        }
      },
      methods: {
        handlePush(){
          this.persons.push(
            {
              id: '004',
              name: 'laoliu',
              age: 18
            }
          )
        },
        handleShift(){
          this.persons.unshift(
            {
              id: '005',
              name: 'laoliao',
              age: 18
            }
          )
        }
      }
    })
  </script>
</body>
</html>